﻿using Microsoft.WindowsAzure.Storage.Blob;
using SpaceNeedle.City6473.Web.Data.Models;
using SpaceNeedle.City6473.Web.Data.Repositories;
using SpaceNeedle.City6473.WebSite.Models;
using SpaceNeedle.SDK.Cloud.Storage;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using SpaceNeedle.City6473.WebSite.Security.Mvc;
using System.Data.Entity;
using System.Web.Configuration;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Auth;
using System.Data.Entity.Validation;

namespace SpaceNeedle.City6473.WebSite.Controllers
{
    public class AdminController : GlobalController
    {
        private AlertRepository alertRepository = new AlertRepository();
        private PhoneRepository phoneRepository = new PhoneRepository();
        private RequestRepository requestRepository = new RequestRepository();
        private RequestItemRepository requestItemRepository = new RequestItemRepository();
        private StatusRepository statusRepository = new StatusRepository();
        private UsersAuthenticationRepository usersRepository = new UsersAuthenticationRepository();

        private Dictionary<string, string> statuses = new Dictionary<string, string>();

        public AdminController()
        {
            foreach (var status in new StatusRepository().GetAll())
            {
                statuses.Add(status.Name, status.Id.ToString());
            }
        }

        #region Alert
        [Secure]
        public ActionResult Alerts()
        {
            var model = new AlertsModel();
            model.Alerts = this.alertRepository.GetAll().ToList();

            return View(model);
        }

        [Secure]
        [HttpPost]
        public ActionResult Alerts(Alert model)
        {
            if (!ModelState.IsValid)
            {
                return RedirectToAction("Alerts", "Admin");
            }

            model.Id = Guid.NewGuid();
            model.CreationDate = DateTime.UtcNow;
            model.CreatedBy = Auth.CurrentUser.Id;

            this.alertRepository.Insert(model);

            WebSiteContent staticContent = new WebSiteContent();
            new UserDeviceRepository().NotifyAll("", /*staticContent.Alerts.ToastMessage +*/ model.Title, "/Views/Alerts.xaml?alertId=" + model.Id.ToString());

            return RedirectToAction("Alerts", "Admin");
        }

        [Secure]
        public ActionResult DeleteAlert(string id)
        {
            var item = alertRepository.GetById(id);

            if (item != null)
            {
                alertRepository.Delete(item);
            }

            return RedirectToAction("Alerts", "Admin");
        }
        #endregion

        #region Phone
        [Secure]
        public ActionResult Phones()
        {
            var model = new PhonesModel();
            model.Phones = this.phoneRepository.GetAll().ToList();
            return View(model);
        }

        [Secure]
        [HttpPost]
        public ActionResult Phones(Phone model)
        {
            if (!ModelState.IsValid)
            {
                return RedirectToAction("Phones", "Admin");
            }

            model.Id = Guid.NewGuid();
            this.phoneRepository.Insert(model);

            return RedirectToAction("Phones", "Admin");
        }

        [Secure]
        public ActionResult DeletePhone(string id)
        {
            var item = phoneRepository.GetById(id);

            if (item != null)
            {
                phoneRepository.Delete(item);
            }

            return RedirectToAction("Phones", "Admin");
        }

        [Secure]
        [HttpPost]
        public ActionResult EditPhone(Phone model)
        {
            phoneRepository.Update(model);
            return RedirectToAction("Phones", "Admin");
        }

        [Secure]
        public ActionResult EditPhone(string id)
        {
            var item = phoneRepository.GetById(id);
            return View(item);
        }

        #endregion

        #region Request
        [Secure]
        public ActionResult Requests()
        {
            var model = new RequestsModel();
            model.Requests = this.requestRepository.GetAll().OrderBy(x=>x.Order).ThenBy(x=>x.Title).ToList();
            model.Icons = this.GetRequestsIcons();

            return View(model);
        }

        [Secure]
        [HttpPost]
        public ActionResult Requests(Request model)
        {
            if (!ModelState.IsValid)
            {
                return RedirectToAction("Requests", "Admin");
            }

            model.Id = Guid.NewGuid();
            this.requestRepository.Insert(model);

            return RedirectToAction("Requests", "Admin");
        }

        [Secure]
        [HttpPost]
        public ActionResult EditRequest(Request model)
        {
            requestRepository.Update(model);

            return RedirectToAction("Requests", "Admin");
        }

        [Secure]
        public ActionResult EditRequest(string id)
        {
            EditRequestModel model = new EditRequestModel();
            model.Request = requestRepository.GetById(id);
            model.Icons = this.GetRequestsIcons();

            return View(model);
        }

        [Secure]
        public ActionResult DeleteRequest(string id)
        {
            var item = requestRepository.GetById(id);

            if (item != null)
            {
                requestRepository.Delete(item);
            }

            return RedirectToAction("Requests", "Admin");
        }

        [Secure]
        public ActionResult MoveRequestUp(string id)
        {
            try
            {
                Guid requestId = new Guid(id);

                var requests = requestRepository.GetAll().OrderBy(x => x.Order).ToList();

                Request previousRequest = null;
                Request currentRequest = null;
                int currentRequestIndex = -1;

                if (requests != null)
                {
                    for (int i = 0; i < requests.Count; i++)
                    {
                        if (requests[i].Id == requestId)
                        {
                            if (i > 0)
                            {
                                previousRequest = requests[i - 1];
                                currentRequest = requests[i];
                                currentRequestIndex = i;
                                break;
                            }
                        }
                    }

                    if(currentRequest != null && previousRequest != null)
                    {
                        requests.Remove(previousRequest);
                        requests.Remove(currentRequest);

                        requests.Insert(currentRequestIndex - 1, currentRequest);
                        requests.Insert(currentRequestIndex, previousRequest);

                        this.UpdateRequestsOrder(requests);

                        return Json(true, JsonRequestBehavior.AllowGet);
                    }
                }
            }
            catch { }

            return Json(false, JsonRequestBehavior.AllowGet);
        }

        [Secure]
        public ActionResult MoveRequestDown(string id)
        {
            try
            {
                Guid requestId = new Guid(id);

                var requests = requestRepository.GetAll().OrderBy(x => x.Order).ToList();

                Request nextRequest = null;
                Request currentRequest = null;
                int currentRequestIndex = -1;

                if (requests != null)
                {
                    for (int i = 0; i < requests.Count; i++)
                    {
                        if (requests[i].Id == requestId)
                        {
                            if (i < requests.Count - 1)
                            {
                                nextRequest = requests[i + 1];
                                currentRequest = requests[i];
                                currentRequestIndex = i;
                                break;
                            }
                        }
                    }

                    if (currentRequest != null && nextRequest != null)
                    {
                        requests.Remove(nextRequest);
                        requests.Remove(currentRequest);

                        requests.Insert(currentRequestIndex, nextRequest);
                        requests.Insert(currentRequestIndex + 1, currentRequest);
                        

                        this.UpdateRequestsOrder(requests);

                        return Json(true, JsonRequestBehavior.AllowGet);
                    }
                }
            }
            catch { }

            return Json(false, JsonRequestBehavior.AllowGet);
        }

        private void UpdateRequestsOrder(List<Request> requests)
        {
            try
            {
                if (requests != null)
                {
                    for (int i = 0; i < requests.Count; i++)
                    {
                        var request = requests[i];
                        request.Order = i + 1;

                        this.requestRepository.Update(request);
                    }
                }
            }
            catch { }
        }
        private List<string> GetRequestsIcons()
        {
            try
            {
                CloudBlobContainer container = AzureStorage.BlobClient.GetContainerReference("icons");

                List<string> blobsAddresses = new List<string>();

                foreach (var blob in container.ListBlobs(null, true))
                {
                    blobsAddresses.Add(blob.Uri.ToString());
                }

                return blobsAddresses;
            }
            catch { }

            return new List<string>();

        }

       

        #endregion

        #region RequestItems

        public List<SelectListItem> DropDownList()
        {
            List<SelectListItem> list = new List<SelectListItem>();
            
            foreach (var status in this.statuses)
            {
                list.Add(new SelectListItem { Text = status.Key, Value = status.Value});    
            }

            return list;
        }

        [Secure]
        public ActionResult RequestItems()
        {
            ViewBag.ListStatus = DropDownList();
            ViewBag.Statuses = this.statuses;

            var model = new RequestItemsModel();
            model.RequestItems = this.requestItemRepository.GetAll().Include(x => x.Request).Include(x=>x.User).OrderByDescending(x => x.CreationDate).ToList();

            return View(model);
        }

        [Secure]
        public JsonResult SetRequestItemStatus(Guid id, int status, string statusInfo)
        {
            return Json(new RequestItemsController().SetStatus(id, status, statusInfo, Auth.CurrentUser.Id), JsonRequestBehavior.AllowGet);
        }

        [Secure]
        public ActionResult DeleteRequestItem(string id)
        {
            if(!new RequestItemsController().Delete(new Guid(id)))
            {
                //Error
            }

            return RedirectToAction("RequestItems", "Admin");
        }

        [Secure]
        [HttpPost]
        public ActionResult EditRequestItem(string id)
        {
            return RedirectToAction("RequestItems", "Admin");
        }

        #endregion

        #region Citizen
        public JsonResult GetCitizen(string id)
        {
            try
            {
                UserRepository users = new UserRepository();
                return Json(users.GetById(id), JsonRequestBehavior.AllowGet);
            }
            catch { }

            return null;
        }
        #endregion

        #region Users
        [Secure]
        public ActionResult Users()
        {
            var model = new UsersModel();
            model.Users = this.usersRepository.GetAll().ToList();
            return View(model);
        }

        [Secure]
        public ActionResult CreateUser()
        {
            //var model = new CreateUserModel();
            //model.Users = this.usersRepository.GetAll().ToList();
            return View(new CreateUserModel());
        }

        [Secure]
        [HttpPost]
        public ActionResult CreateUser(CreateUserModel model)
        {
            if (!ModelState.IsValid)
            {
                return View(model);
            }

            if(this.usersRepository.GetAll().Where(x=>x.Email == model.Email).SingleOrDefault() != null)
            {
                ModelState.AddModelError("Email", "Este e-mail já está cadastrado");
                return View(model);
            }

            UsersAuthentication user = new UsersAuthentication();
            user.Id = Guid.NewGuid();
            user.Name = model.Name;
            user.Email = model.Email;
            user.Password = SpaceNeedle.City6473.Web.Data.Security.Encode(model.Password);
            user.IsActive = model.IsActive;
            user.Roles = model.Roles;

            this.usersRepository.Insert(user);

            return RedirectToAction("Users", "Admin");
        }

        [Secure]
        public ActionResult DeleteUser(string id)
        {
            var item = usersRepository.GetById(id);

            if (item != null)
            {
                usersRepository.Delete(item);
            }

            return RedirectToAction("Users", "Admin");
        }

        [Secure]
        [HttpPost]
        public ActionResult EditUser(EditUserModel model)
        {
            if (!ModelState.IsValid)
            {
                return View(model);
            }

            if (model.OldEmail != model.Email && this.usersRepository.GetAll().Where(x => x.Email == model.Email).SingleOrDefault() != null)
            {
                ModelState.AddModelError("Email", "Este e-mail já está cadastrado");
                return View(model);
            }

            var user = usersRepository.GetById(model.Id);

            user.Id = model.Id;
            user.Name = model.Name;
            user.Email = model.Email;
            user.IsActive = model.IsActive;
            user.Roles = model.Roles;

            usersRepository.Update(user);

            return RedirectToAction("Users", "Admin");
        }

        [Secure]
        public ActionResult EditUser(string id)
        {
            var item = usersRepository.GetById(id);

            if(item == null)
            {
                return RedirectToAction("Users", "Admin");
            }

            EditUserModel model = new EditUserModel();
            model.OldEmail = item.Email;

            model.Id = item.Id;
            model.Name = item.Name;
            model.Email = item.Email;
            model.IsActive = item.IsActive;
            model.Roles = item.Roles;

            return View(model);
        }

        #endregion
    }
}